#ifndef CVIMRENDER_RENDERABLELINES_H_INCLUDED
#define CVIMRENDER_RENDERABLELINES_H_INCLUDED

#include <boost/pool/object_pool.hpp>
#include <boost/pool/pool.hpp>
#include <General/cvMemory.h>
#include <list>
#include <vector>


/// pre decl
namespace cvImmediateModeRenderer
{
	class RenderableLines;
	class Line;
};
#include "../cvIRender.h"
#include "../cvIPrimitives.h"

namespace cvImmediateModeRenderer
{
	struct line_struct_color
	{	RGBAf c1;
		RGBAf c2;
	} HINT_PACKED;

	struct line_struct_vert
	{	cvVert v1;
		cvVert v2;
	} HINT_PACKED;



	/// impl interface
	class Line : public cvRenderInterface::Line
	{
		public:
			Line();
			Line(RenderableLines * batch, size_t index);

			Line * verts(const cvVert &v1, const cvVert &v2);
			Line * color(const RGBAf &col);
			Line * colorv1(const RGBAf &col);
			Line * colorv2(const RGBAf &col);
			Line * verts(cvVert *v1, cvVert *v2);
			Line * colorv1(RGBAf *col);
			Line * colorv2(RGBAf *col);

			RenderableLines * m_batch;
			size_t m_pos;		// index in internal array
	};

	/// impl interface
	class RenderableLines : public cvRenderInterface::BatchObject<cvRenderInterface::Line>
	{
		public:
			RenderableLines();
			virtual ~RenderableLines();

			/// Pool where Renderableline rips out of its memory.
			static boost::pool<> m_linebatch_pool;
			void * operator new(size_t size);
			void operator delete(void * ptr);

			void prepareDraw();

			void draw();

			/// maps primitives to array.
			void map(cvRenderInterface::Line ** array, size_t count);

			/// drops primitives from BatchObject.
			void drop(cvRenderInterface::Line ** array, size_t count);

			/// Adds new singleshot primitives - returns temporary primitive.
			cvRenderInterface::Line * mapSingleshot();

			/// drop all primitives, but don't release memory.
			void flush();

			/// returns count of primitives in this BatchObject
			size_t size();

			int renderableType();

		private:
			///@NOTE: storgate taken from global pools: line_struct_color, line_struct_vert and Line*, remember to release.
			typedef std::vector<line_struct_vert, cvPoolAllocator<line_struct_vert>::CON> vdat_vector_t;
			typedef std::vector<line_struct_color, cvPoolAllocator<line_struct_color>::CON> cdat_vector_t;
			typedef std::list<Line*, cvPoolAllocator<Line*>::RAN > mod_list_t;

			friend class Line;

			///	Continous array(s) of data which can be fed directly to OpenGL (visible lines are kept in front/back of the vector?)
			vdat_vector_t m_draw_verts;
			cdat_vector_t m_draw_colors;
			size_t m_rendcount;

			// List of modifiable lines.
			mod_list_t m_modifyhandles;
			// when some primitives have been dropped the holes are automatically
			// filled as we write primitves into the buffer.
			int m_invalid_index;

			// local pool for modifiable lines. (so memory of unfreed handles will be deleted in destructor)
			boost::pool<> m_handlepool;

			//ImmediateModeRenderer * m_render;
	};

};	// cvImmediateModeRenderer
#endif // CVIMRENDER_RENDERABLELINES_H_INCLUDED
